#include <stdio.h>
#include <stdlib.h>
#include "mystack.h"

template <typename T>
stack<T>::stack( )
	    : count (0), top(0)
{

}

template <typename T>
stack<T>::~stack()
{
	if (top != 0)
	{
		while ( top->next != 0 )
		{
			top = top->next;	
			delete top->prev;
			top->prev = 0;
		}
		delete top;
	}
}

template <typename T>
void stack<T>::stack_push(T value)
{
	stack_ok(push);
	T* val = new T;
	val->value = 0;
	if ( top == 0 )
	{
		top = val;                        // create a new elem of a stack
	
	}
	else
	{
		top->prev = val;
		
	top->value = value;                 // writing value into the new elem of a stack
	(stack->count)++;                   // increasing count
	stack_ok(top);          // checking the stack
	}
}

template <typename T>
int stack<T>::stack_pop()
{
	int a = 0;                         // temporary variable
	stack::stack_ok(T* top);           // checking the stack
	a = top->value;                    // saving value in the temporary variable
	top->value = 0;                    // cleaning 
	top = top->next;                   // changing value of pointer
	top->prev->next = 0;               // cleaning
	(stack->count)++;                  // decrementing
	stack::stack_ok(T* top);           // checking the stack
}

template <typename T>
bool stack<T>::stack_ok( )
{
	
	if ( count < 0)
		throw std::overflow_error("Negative element count");
	if (((count == 0) && (top != 0))   ||  ((count != 0) && (top == 0)))
		throw std::runtime_error("Count and top mismatch");
	if( top != 0  )
	{
		Elem<T>* pointer = top;
		int counter_new = 0;
		if( pointer->prev == 0 )
			throw std::runtime_error("invalid top element (prev != 0)");	
		while( (counter_new < (count-1)) && (pointer->next != 0))
		{
			if( pointer->next != pointer->next->prev ) 
				throw std::runtime_error("Invalid linking in stack");
			pointer = pointer->next;
			counter_new++;
		}
		if( counter_new != (count-1) )
			throw std::runtime_error("invalid element count");
	}
	return true;

}

template <typename T>
bool stack<T>::stack_dump(T* top)
{
	T* val;
	val = top;
	printf("count- %i\ntop-   %p\n", count,top);
	while ( val->next = 0 )
	{
		printf("prev- %p\nnext- %p\nvalue- %i\n",top->prev,top->next,top->value);
		val = val->next;	
	}
}

